package com.ltu.timkor6.gamesite.games.missingbits.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.ltu.timkor6.gamesite.games.missingbits.shared.Question;
import com.ltu.timkor6.gamesite.shared.CompositeAbstract;
import com.ltu.timkor6.gamesite.shared.Result;

public class MissingBitsComposite extends CompositeAbstract
{
	private MissingBits missingBits;
	
	private int questionNumber = 0;
	private int numberOfGames = 0;
	private int points = 0;
	
	private int gameTime = 0;
	private int questionTime = 0;
	
	private TextBox textNumberOfQuestions;
	private TextBox textAnswer;
	private Label labelQuestions;
	private Label labelPoints;
	private Label labelGameTime;
	private Label labelQuestionTime;
	
	private Timer t;
	//private List<GameObject> gameObjects;
	
	private VerticalPanel game;
	private HorizontalPanel answer;
	
	public MissingBitsComposite(MissingBits missingBits)
	{
		this.missingBits = missingBits;
		
		// Title
		final Label title = new Label("Game: Missing Bits");
		title.setStyleName("panelHeader");
		panel.add(title);
		
		loadGame();
		panel.add(game);
		
		initWidget(panel);
	}
	
	/**
	 * Set up the game.
	 */
	public void loadGame()
	{
		// TODO Game - Missing Bits
		game = new VerticalPanel();
		
		Label labelNumberOfQuestions = new Label("Number of questions");
		textNumberOfQuestions = new TextBox();
		textNumberOfQuestions.setText("5");
		textNumberOfQuestions.addKeyPressHandler(new KeyPressHandler()
		{
			public void onKeyPress(KeyPressEvent event)
			{
				if(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER)
				{
					start();
				}
			}
		});
		
		game.add(labelNumberOfQuestions);
		game.add(textNumberOfQuestions);
		
		Button start = new Button("Start!");
		start.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				start();
			}
		});
		game.add(start);
		
		this.textNumberOfQuestions.setFocus(true);
	}
	
	/**
	 * First screen.
	 */
	private void start()
	{
		String questions = this.textNumberOfQuestions.getText().trim();
		if(questions.length() == 0)
		{
			questions = "0";
		}
		try
		{
			numberOfGames = Integer.parseInt(questions);
			if(0 < numberOfGames)
			{
				this.missingBits.start(numberOfGames);
			}
		}
		catch(NumberFormatException e)
		{
			
		}
	}
	
	/**
	 * Each question.
	 * @param question
	 */
	public void question(Question question)
	{
		game.clear();
		questionNumber++;
		questionTime = 0;
		
		labelQuestions = new Label("Question " + question.getQuestionNumber() + " of " + numberOfGames);
		labelPoints = new Label("Points: " + points);
		labelGameTime = new Label("Game time: " + formatTime(gameTime));
		labelQuestionTime = new Label("Question time: " + formatTime(questionTime));
		
		game.add(labelQuestions);
		game.add(labelPoints);
		game.add(labelGameTime);
		game.add(labelQuestionTime);
		
		expression(question);
		
		answer = new HorizontalPanel();
		
		textAnswer = new TextBox();
		textAnswer.addKeyPressHandler(new KeyPressHandler()
		{
			public void onKeyPress(KeyPressEvent event)
			{
				if(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER)
				{
					answer();
				}
			}
		});
		Button submit = new Button("Answer");
		submit.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				answer();
			}
		});
		
		answer.add(textAnswer);
		answer.add(submit);
		
		game.add(answer);
		
		textAnswer.setFocus(true);
		
		checkTime(1000);
	}
	
	/**
	 * Send a answer back to server.
	 */
	private void answer()
	{
		String answer = this.textAnswer.getText().trim();
		this.missingBits.sendAnswer(answer);
	}
	
	/**
	 * Next question screen.
	 * @param points
	 */
	public void showNextQuestion(int points)
	{
		answer.clear();
		t.cancel();
		
		updatePoints(points);
		
		String status = (0 < points) ? "Correct" : "Wrong answer" ;
		Label info = new Label(status);
		answer.add(info);
		
		if(questionNumber == numberOfGames)
		{
			Button submit = new Button("Show results");
			submit.addClickHandler(new ClickHandler()
			{
				public void onClick(ClickEvent event)
				{
					missingBits.getResult();
				}
			});
			answer.add(submit);
			
			submit.setFocus(true);
		}
		else
		{
			Button submit = new Button("Next question");
			submit.addClickHandler(new ClickHandler()
			{
				public void onClick(ClickEvent event)
				{
					missingBits.getQuestion();
				}
			});
			answer.add(submit);
			
			submit.setFocus(true);
		}
	}
	
	public void showResult(Result result)
	{
		t.cancel();
		
		answer.clear();
	}
	
	private void updatePoints(int addPoints)
	{
		this.points += addPoints;
		this.labelPoints.setText("Points: " + points);
	}
	
	private void expression(Question question)
	{
		Label label = new Label(question.getFirst() + " " + question.getSign() + " " + question.getSecond() + " = ?");
		
		game.add(label);
	}
	
	private String formatTime(int seconds)
	{
		int intMinutes = seconds / 60;
		int intSeconds = seconds % 60;
		
		String stringMinutes = NumberFormat.getFormat("00").format(intMinutes);
		String stringSeconds = NumberFormat.getFormat("00").format(intSeconds);
		
		return stringMinutes + ":" + stringSeconds;
	}
	
	private void checkTime(int time)
	{
		t = new Timer()
		{
			public void run()
			{
				labelGameTime.setText("Game time: " + formatTime(gameTime));
				labelQuestionTime.setText("Question time: " + formatTime(questionTime));
				
				gameTime++;
				questionTime++;
			}
		};
		
		t.scheduleRepeating(time);
	}
}
